/**
 * 
 */
package idv.takeshi.software.productline.bookstore.presentation.web.controller;

import java.security.Principal;
import java.util.Locale;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import idv.takeshi.software.productline.bookstore.application.service.InvalidOrderIdException;
import idv.takeshi.software.productline.bookstore.application.service.InvalidPickingListSequenceException;
import idv.takeshi.software.productline.bookstore.application.service.MaintainOrdersService;
import idv.takeshi.software.productline.bookstore.application.service.MaintainPickingListException;
import idv.takeshi.software.productline.bookstore.application.service.MaintainPickingListsService;
import idv.takeshi.software.productline.bookstore.application.service.MaintainUserAccountsService;
import idv.takeshi.software.productline.bookstore.domain.model.order.Order;
import idv.takeshi.software.productline.bookstore.domain.model.order.PickingList;
import idv.takeshi.software.productline.bookstore.domain.model.useraccount.UserAccount;
import idv.takeshi.software.productline.bookstore.utils.text.ServletPathStringUtils;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * A controller for maintaining pickingList operations.
 * @author takeshi
 *
 */
@Controller("maintainPickingListController")
@RequestMapping(value = "/pickingLists")
public class MaintainPickingListController {
	
	private static final Log log = LogFactory.getLog(MaintainPickingListController.class);
	
	@Autowired
	private MaintainOrdersService maintainOrdersService;
	
	@Autowired
	private MaintainUserAccountsService maintainUserAccountsService;
	
	@Autowired
	private MaintainPickingListsService maintainPickingListsService;
	
	@Autowired
	private MessageSource messageSource;
	
	@RequestMapping(value = "/listPickingLists.html", method = RequestMethod.GET)
	public void listPickingLists(
			@RequestParam Long orderId, @RequestParam String previousPath, 
			ModelMap modelMap, HttpServletRequest request){
		Order order = null;
		Set<PickingList> pickingLists = null;
		order = this.maintainOrdersService.getOrderById(orderId);
		pickingLists = order.getPickingLists();
		
		String currentPath = request.getServletPath();
		currentPath += StringUtils.isNotBlank(request.getQueryString())? "?" + request.getQueryString(): "";
		
		modelMap.addAttribute("order", order);
		modelMap.addAttribute("pickingLists", pickingLists);
		modelMap.addAttribute("currentPath", currentPath);
		modelMap.addAttribute("previousPath", previousPath);
	}
	
	@RequestMapping(value = "/seePickingList.html", method = RequestMethod.GET)
	public void loadSinglePickingList(
			@RequestParam Long orderId, @RequestParam int pickingListSequence,
			@RequestParam String previousPath, Principal principal, ModelMap modelMap){
		
		UserAccount clerk = null;
		UserAccount owner = null;
		Order order = null;
		PickingList pickingList = null;
		
		clerk = this.maintainUserAccountsService.getUserAccountByName(principal.getName());
		owner = this.maintainOrdersService.getUserAccountByOrderId(orderId);
		order = this.maintainOrdersService.getOrderById(orderId);
		pickingList = order.getPickingList(pickingListSequence);
		
		modelMap.addAttribute("clerk", clerk);
		modelMap.addAttribute("userAccount", owner);
		modelMap.addAttribute("order", order);
		modelMap.addAttribute("previousPath", previousPath);
		modelMap.addAttribute("pickingList", pickingList);
	}
	
	@RequestMapping(value = "/receivePickingList.html", method = RequestMethod.GET)
	public void goToReceivePickingListView(){/*DO NOTHING*/}
	
	@RequestMapping(value = "/receivePickingList.html", method = RequestMethod.POST)
	public String changeToReceivedStatus(@RequestParam Long orderId, @RequestParam int pickingListSequence,
			HttpServletRequest request, Locale locale){
		
		String newPath = request.getServletPath();
		StringBuffer msg = new StringBuffer();
		
		try {
			this.maintainPickingListsService.receivePickingList(orderId, pickingListSequence);
		} catch(InvalidOrderIdException e) {
			log.warn("user input invalid orderId:" + orderId, e);
			msg.append("?errorMsg=");
			msg.append(this.messageSource.getMessage("pickingLists.seePickingList.msg.invalidOrderId", 
					new Object[]{orderId}, locale));
		} catch(InvalidPickingListSequenceException e){
			log.warn("user input invalid pickingList sequence:" + pickingListSequence, e);
			msg.append("?errorMsg=");
			msg.append(this.messageSource.getMessage("pickingLists.seePickingList.msg.invalidPickingListSequence", 
					new Object[]{pickingListSequence}, locale));
		} catch(Exception e){
			log.error("Unknown error occurs", e);
			msg.append("?errorMsg=");
			msg.append(this.messageSource.getMessage("pickingLists.seePickingList.msg.unknownError", 
					null, locale));
		}
		
		if(msg.length() == 0){
			msg.append("?normalMsg=");
			msg.append(this.messageSource.getMessage("pickingLists.seePickingList.msg.success", 
					new Object[]{orderId, pickingListSequence}, locale));
		} else{
			msg.append("&orderId=" + orderId + "&pickingListSequence=" + pickingListSequence);
		}
		
		return "redirect:" + newPath + msg.toString();
	}
}
